Passed
Push — master ( e23d96...6ebda8 )
by Rafael S.
01:38
created

mulaw.js ➔ decodeSample   A

Complexity

Conditions 2
Paths 8

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 1
c 0
b 0
f 0
nc 8
rs 10
nop 1
1
/*
2
 * alawmulaw: A-Law and mu-Law codecs in JavaScript.
3
 * https://github.com/rochars/alawmulaw
4
 *
5
 * Copyright (c) 2018 Rafael da Silva Rocha.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining
8
 * a copy of this software and associated documentation files (the
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sublicense, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 */
27
28
/**
29
 * @fileoverview mu-Law codec.
30
 */
31
32
/** @module alawmulaw/mulaw */
33
34
/**
35
 * @type {number}
36
 * @private
37
 */
38
const BIAS = 0x84;
39
/**
40
 * @type {number}
41
 * @private
42
 */
43
const CLIP = 32635;
44
/**
45
 * @type {Array<number>}
46
 * @private
47
 */
48
const encodeTable = [
49
    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
50
    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
51
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
52
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
53
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
54
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
55
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
56
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
57
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
58
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
61
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
62
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
63
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
64
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7];
65
/**
66
 * @type {Array<number>}
67
 * @private
68
 */
69
const decodeTable = [0,132,396,924,1980,4092,8316,16764];
70
71
/**
72
 * Encode a 16-bit linear PCM sample as 8-bit mu-Law.
73
 * @param {number} sample A 16-bit PCM sample
74
 * @return {number}
75
 */
76
export function encodeSample(sample) {
77
  /** @type {number} */
78
  let sign;
79
  /** @type {number} */
80
  let exponent;
81
  /** @type {number} */
82
  let mantissa;
83
  /** @type {number} */
84
  let muLawSample;
85
  /** get the sample into sign-magnitude **/
86
  sign = (sample >> 8) & 0x80;
87
  if (sign != 0) sample = -sample;
88
  if (sample > CLIP) sample = CLIP;
89
  /** convert from 16 bit linear to ulaw **/
90
  sample = sample + BIAS;
91
  exponent = encodeTable[(sample>>7) & 0xFF];
92
  mantissa = (sample >> (exponent+3)) & 0x0F;
93
  muLawSample = ~(sign | (exponent << 4) | mantissa);
94
  /** return the result **/
95
  return muLawSample;
96
}
97
98
/**
99
 * Decode a 8-bit mu-Law sample as 16-bit PCM.
100
 * @param {number} muLawSample The 8-bit mu-Law sample
101
 * @return {number}
102
 */
103
export function decodeSample(muLawSample) {
104
  /** @type {number} */
105
  let sign;
106
  /** @type {number} */
107
  let exponent;
108
  /** @type {number} */
109
  let mantissa;
110
  /** @type {number} */
111
  let sample;
112
  muLawSample = ~muLawSample;
113
  sign = (muLawSample & 0x80);
114
  exponent = (muLawSample >> 4) & 0x07;
115
  mantissa = muLawSample & 0x0F;
116
  sample = decodeTable[exponent] + (mantissa << (exponent+3));
117
  if (sign != 0) sample = -sample;
118
  return sample;
119
}
120
121
/**
122
 * Encode 16-bit linear PCM samples into 8-bit mu-Law samples.
123
 * @param {!Int16Array} samples A array of 16-bit PCM samples.
124
 * @return {!Uint8Array}
125
 */
126
export function encode(samples) {
127
  /** @type {!Uint8Array} */
128
  let muLawSamples = new Uint8Array(samples.length);
129
  for (let i=0; i<samples.length; i++) {
130
    muLawSamples[i] = encodeSample(samples[i]);
131
  }
132
  return muLawSamples;
133
}
134
135
/**
136
 * Decode 8-bit mu-Law samples into 16-bit PCM samples.
137
 * @param {!Uint8Array} samples A array of 8-bit mu-Law samples.
138
 * @return {!Int16Array}
139
 */
140
export function decode(samples) {
141
  /** @type {!Int16Array} */
142
  let pcmSamples = new Int16Array(samples.length);
143
  for (let i=0; i<samples.length; i++) {
144
    pcmSamples[i] = decodeSample(samples[i]);
145
  }
146
  return pcmSamples;
147
}
148